package com.moli.iov.sys.remote.impl;

import com.moli.iov.base.model.dto.req.SysParamSettingsReqDto;
import com.moli.iov.base.remote.ISysParamSettingsRemoteService;
import com.moli.iov.exception.BusinessException;
import com.moli.iov.model.dto.req.PageExtend;
import com.moli.iov.notify.remote.INoticeRemoteService;
import com.moli.iov.rest.RestResponse;
import com.moli.iov.sys.enums.CompanyStatusEnum;
import com.moli.iov.sys.model.dto.req.ClientDetailsReqDto;
import com.moli.iov.sys.model.dto.req.CompanyDto;
import com.moli.iov.sys.model.dto.req.UserDto;
import com.moli.iov.sys.model.po.ClientDetails;
import com.moli.iov.sys.model.po.Company;
import com.moli.iov.sys.model.po.User;
import com.moli.iov.sys.remote.IClientDetailsRemoteService;
import com.moli.iov.sys.remote.ICompanyRemoteService;
import com.moli.iov.sys.remote.IUserRemoteService;
import com.moli.iov.sys.service.IClientDetailsService;
import com.moli.iov.sys.service.ICompanyService;
import com.moli.iov.sys.service.IUserService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 企业远程调用 服务类
 * </p>
 *
 * @author zql
 * @since 2019/9/4 15:04
 */
@Slf4j
@Service(group = "${service.group}")
public class CompanyRemoteServiceImpl implements ICompanyRemoteService {

  @Autowired
  private ICompanyService companyService;

  @Autowired
  private IClientDetailsService clientDetailsService;

  @Autowired
  private IClientDetailsRemoteService clientDetailsRemoteService;

  @Autowired
  private IUserService userService;

  @Autowired
  private IUserRemoteService userRemoteService;

  @Reference(group = "${service.group}", check = false)
  private ISysParamSettingsRemoteService sysParamSettingsRemoteService;

  @Reference(group = "${service.group}", check = false)
  private INoticeRemoteService noticeRemoteService;

  /**
   *
   * 分页查询企业列表
   *
   * @param companyDto
   * @return
   */
  @Override
  public RestResponse<PageExtend<Company>> listCompanyOfPage(CompanyDto companyDto) {

    PageExtend<Company> companyPageExtend = companyService.listCompanyOfPage(companyDto);

    if(companyPageExtend.getRecords() != null && !companyPageExtend.getRecords().isEmpty()){
      companyPageExtend.getRecords().forEach(company ->
        company.setStatusStr(CompanyStatusEnum.getMsg(company.getStatus())));
    }
    return RestResponse.success(companyPageExtend);
  }

  /**
   *
   * 查询企业列表
   *
   * @param companyDto
   * @return
   */
  @Override
  public RestResponse<List<Company>> listCompany(CompanyDto companyDto) {
    List<Company> companies = companyService.listCompany(companyDto);
    return RestResponse.success(companies);
  }

  /**
   * 增加企业
   * @param companyDto
   * @return
   */
  @Transactional
  @Override
  public RestResponse saveCompany(CompanyDto companyDto) {

    saveValid(companyDto);

    Long companyId = companyService.saveCompany(companyDto);
    if(companyId == null){
      throw new BusinessException("增加失败");
    }
    companyDto.setCompanyId(companyId);

    //增加企业客户端信息
    RestResponse restResponse = clientDetailsRemoteService
        .saveClientDetails(companyId);
    if(!restResponse.flag){
      throw new BusinessException("增加企业客户端信息失败");
    }

    //初始化其它参数
    initOther(companyDto);

    return RestResponse.success();
  }

  /**
   * 添加企业初始化其它服务参数
   * @param companyDto
   */
  @Async
  public void initOther(CompanyDto companyDto){
    try {
      //1）生成企业的超级管理员账号；（包括角色与账号；本期 不考虑编辑时修改用户邮箱后，超级管理员变更的需求）
      userRemoteService.saveSuperAdminOfCompany(companyDto);
    }catch(Exception e){
      log.error("生成企业的超级管理员账号", e);
    }

    try{
      // 2）生成企业的控车通知设置项；3）生成企业的报警通知设置项；
      noticeRemoteService.addDefaultNotice(companyDto.getCompanyId());
    }catch(Exception e){
      log.error("生成企业的控车通知设置项和报警通知设置项异常", e);
    }

    try{
      //生成企业的系统参数（取默认值）。
      SysParamSettingsReqDto sysParamSettingsReqDto = new SysParamSettingsReqDto();
      sysParamSettingsReqDto.setCompanyName(companyDto.getCompanyName());
      sysParamSettingsReqDto.setCompanyId(companyDto.getCompanyId());
      sysParamSettingsReqDto.setSysUserId(companyDto.getSysUserId());
      RestResponse restResponse = sysParamSettingsRemoteService
          .initSysParamSettings(sysParamSettingsReqDto);
      log.info("生成企业的系统参数（取默认值）返回数据：{}", restResponse);
    }catch(Exception e){
      log.error("生成企业的系统参数（取默认值）异常", e);
    }
  }

  /**
   * 添加企业 校验
   * @param companyDto
   * @return
   */
  private void saveValid(CompanyDto companyDto){
    CompanyDto queryCompanyDto = new CompanyDto();
    queryCompanyDto.setAccurateCompanyName(companyDto.getCompanyName());
    List<Company> companies = companyService.listCompany(queryCompanyDto);

    if(companies != null && !companies.isEmpty()){
      throw new BusinessException("企业名称已经存在");
    }

    queryCompanyDto.setAccurateCompanyName(null);
    queryCompanyDto.setEmail(companyDto.getEmail());
    companies = companyService.listCompany(queryCompanyDto);
    if(companies != null && !companies.isEmpty()){
      throw new BusinessException("负责人邮箱已经存在");
    }

    UserDto userDto = new UserDto();
    userDto.setEmail(companyDto.getEmail());
    List<User> users = userService.listUsers(userDto);
    if(users != null && !users.isEmpty()){
      throw new BusinessException("负责人邮箱已经存在");
    }

    queryCompanyDto = new CompanyDto();
    queryCompanyDto.setCorporationPhone(companyDto.getCorporationPhone());
    companies = companyService.listCompany(queryCompanyDto);
    if(companies != null && !companies.isEmpty()){
      throw new BusinessException("负责人手机已经存在");
    }
  }

  /**
   * 修改企业
   * @param companyDto
   * @return
   */
  @Override
  public RestResponse updateCompanyByCompanyId(CompanyDto companyDto) {

    updateValid(companyDto);

    if(companyService.updateCompanyByCompanyId(companyDto) > 0){
      return RestResponse.success();
    }
    return RestResponse.failure("修改失败");
  }

  /**
   * 修改校验
   * @param companyDto
   */
  public void updateValid(CompanyDto companyDto){
    CompanyDto companyQuery = new CompanyDto();
    companyQuery.setNeCompanyId(companyDto.getCompanyId());
    companyQuery.setCorporationPhone(companyDto.getCorporationPhone());
    List<Company> companies = companyService.listCompany(companyQuery);
    if(companies != null && !companies.isEmpty()){
      throw new BusinessException("负责人手机已存在");
    }
  }

  /**
   * 获取单个企业
   * @param companyDto
   * @return
   */
  @Override
  public RestResponse<Company> getCompanyByCompanyId(CompanyDto companyDto) {
    Company company = companyService.getCompanyByCompanyId(companyDto);
    if(company == null) {
      return RestResponse.failure("企业id不存在");
    }

    ClientDetails clientDetails =
        clientDetailsService.getClientDetails(new ClientDetailsReqDto(companyDto.getCompanyId()));
    company.setClientDetails(clientDetails);
    return RestResponse.success(company);
  }

  /**
   * 校验企业id
   * @param companyId
   * @return
   */
  @Override
  public Company companyValid(Long companyId) {
    CompanyDto companyDto = new CompanyDto();
    companyDto.setCompanyId(companyId);
    List<Company> companies = companyService.listCompany(companyDto);
    if(companies == null || companies.isEmpty()){
      throw new BusinessException("企业id不存在");
    }

    Company company = companies.get(0);
    if(company.getStatus() == CompanyStatusEnum.DISABLED.getFlag()){
      throw new BusinessException("企业已停用");
    }

    return company;
  }

  /**
   * 企业id集合查询列表
   * @param companyIds
   * @return
   */
  @Override
  public RestResponse<Map<Long, String>> listCompanyByCompanyIds(List<Long> companyIds) {

    if(companyIds == null || companyIds.isEmpty()){
      return RestResponse.failure("企业id不能为空");
    }

    CompanyDto queryCompanyDto = new CompanyDto();
    queryCompanyDto.setCompanyIds(companyIds);
    List<Company> companies = companyService.listCompany(queryCompanyDto);

    Map<Long, String> companyMap = new HashMap<>();
    companies.forEach(company -> companyMap.put(company.getCompanyId(), company.getCompanyName()));

    return RestResponse.success(companyMap);
  }
}
